from django.shortcuts import render
from django.views import View
from django import http
from django.core.paginator import Paginator
from django.utils import timezone

from contents.utils import get_categories
from .models import GoodsCategory,SKU,GoodsVisitCount
from meid_duo.utils.response_code import RETCODE
from .utils import get_breadcrumb

# Create your views here.
class ListView(View):
    """商品列表界面"""

    def get(self, request, category_id, page_num):
        try:
            category = GoodsCategory.objects.get(id=category_id)   # 根据前端传来的id去数据库获取数据
        except GoodsCategory.DoesNotExist:
            return http.HttpResponseForbidden('商品类别不存在')

        # 页面的不同方法排序（价格，人气，默认创建时间）
        sort = request.GET.get("sort",'default')
        if sort == 'price':
            sort_fields = 'price'
        elif sort == 'hot':
            sort_fields = '-sales'
        else:
            sort_fields = 'create_time'
        # 面包屑导航
        sku_qs = category.sku_set.filter(is_launched=True).order_by(sort_fields)
        # 分页
        paginator = Paginator(sku_qs,5)
        page_skus = paginator.page(page_num)
        total_page = paginator.num_pages
        # 数据返回
        context = {
            'categories': get_categories(),  # 频道分类
            'breadcrumb': get_breadcrumb(category),  # 面包屑导航
            'sort': sort,  # 排序字段
            'category': category,  # 第三级分类
            'page_skus': page_skus,  # 分页后数据
            'total_page': total_page,  # 总页数
            'page_num': page_num,  # 当前页码
        }
        return render(request,'list.html',context)


class HotGoodsView(View):
    """热销排行数据"""

    def get(self, request, category_id):

        try:  # 获取数据
            category = GoodsCategory.objects.get(id=category_id)
        except GoodsCategory.DoesNotExist:
            return http.HttpResponseForbidden('商品类别不存在')

        # 根据销量排行获取前两个
        skus_qs = category.sku_set.filter(is_launched=True).order_by('-sales')[0:2]
        hot_skus = []
        # 对得到的两个数据包装
        for sku in skus_qs:
            hot_skus.append({
                'id':sku.id,
                'name':sku.name,
                'price':sku.price,
                'default_image_url':sku.default_image.url

            })

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'hot_skus': hot_skus})


# class DetailView(View):
#     """商品详情页残缺版"""
#     def get(self,request,sku_id):
#
#         try:
#             # 通过前端传来的id取数据库中查找商品信息
#             sku = SKU.objects.get(id= sku_id)
#         except SKU.DoesNotExist:
#             return render(request,'404.html')
#         category = sku.category    # 获取当前sku所对应的所有三级分类
#
# # 获取sku的所有规格型号，因为sku未关联spu规格信息表，而spu与规格表有外建关联，所以通过spu（主表）去查规格信息表（从表）
#         spu = sku.spu  # 获取当前sku所对应的spu信息
#         spu_spec_qs = spu.specs.order_by(("id")) # 查寻所有的spu规格
#         for spec in spu_spec_qs:
#             # 通过规格信息表去查询每个规格下的所有规格选项表（例如：颜色规格下黄色，红色等规格选项）
#             spec_options_qs = spec.options.all()
#             for option in spec_options_qs:  # 遍历当前规格下的所有选项
#                 option.sku_id = 4  #  给每个选项都绑定一个id，当点击时，跳转到对应id页面（此处以写死）
#             spec.spec_options = spec_options_qs # 把规格下的所有选项绑定到规格对象的spec_options属性上
#
#         context={
#             "categories": get_categories(),   # 商品分类
#             "breadcrumb": get_breadcrumb(category),  # 面包屑导航
#             "spu":spu,  # 当前sku所对应的spu模型类
#             "sku":sku, # 当前显示的sku模型类
#             "category":category,  # 当前的显示sku所属的三级类别
#             'spec_qs': spu_spec_qs, # 当前sku商品的所有规格及规格选项
#         }
#
#         return render(request,'detail.html',context)      #             #


class DetailView(View):
    """商品完整详情页"""
    def get(self,request,sku_id):

        try:
            # 通过前端传来的id取数据库中查找商品信息
            sku = SKU.objects.get(id= sku_id)
        except SKU.DoesNotExist:
            return render(request,'404.html')
        category = sku.category    # 获取当前sku所对应的所有三级分类
        spu = sku.spu  # 获取当前sku所对应的spu信息

        # 1.准备当前商品的规格选项列表 [8, 11]
        # 获取出当前正显示的sku商品的规格选项id列表
        current_sku_spec_qs = sku.specs.order_by("spec_id")  # 获取当前sku的所有规格选项
        current_sku_spec_qs_ids = []
        for current_sku in current_sku_spec_qs:  # 获取每一个选项
            # 通过选项获得每一个选项的option_id，并将其添加到字典中去
            current_sku_spec_qs_ids.append(current_sku.option_id)

        # 2.构造规格选择仓库
        #   {(8, 11): 3, (8, 12): 4, (9, 11): 5, (9, 12): 6, (10, 11): 7, (10, 12): 8}
        temp_sku_qs = spu.sku_set.all()   # 准备当前spu下的所有sku
        spec_sku_map = {}   # 构造仓库
        for temp_sku in temp_sku_qs:
            # 获取每一个sku下的所有规格选项
            temp_spec_qs = temp_sku.specs.order_by("spec_id")
            temp_sku_option_ids = []
            for temp_spec in temp_spec_qs:  # 获取每一个选项
                # 通过选项获得每一个选项的option_id，并将其添加到字典中去
                temp_sku_option_ids.append(temp_spec.option_id)
        # 将得到的字典转化为元组作为仓库字典的键，且以当前sku的id作为值，添加到字典中
            spec_sku_map[tuple(temp_sku_option_ids)] = temp_sku.id

        # 3.组合 并找到sku_id 绑定
# 获取sku的所有规格型号，因为sku未关联spu规格信息表，而spu与规格表有外建关联，所以通过spu（主表）去查规格信息表（从表）
        spu_spec_qs = spu.specs.order_by(("id")) # 查寻当前所有的spu规格
        for index,spec in enumerate(spu_spec_qs):
            # 通过规格信息表去查询每个规格下的所有规格选项表（例如：颜色规格下黄色，红色等规格选项）
            spec_options_qs = spec.options.all()
            temp_option_ids = current_sku_spec_qs_ids[:]  # 复制一个新的当前显示商品的规格选项列表
            for option in spec_options_qs:  # 遍历当前规格下的所有选项
                temp_option_ids[index] = option.id  # 动态更改列表中的值，（该列表为仓库字典的键）
                # 通过上面动态的键来获取相对应的值，即id，作为返回给前端动态的id，实现不同选项规格时页面刷新
                option.sku_id = spec_sku_map.get(tuple(temp_option_ids))
            spec.spec_options = spec_options_qs # 把规格下的所有选项绑定到规格对象的spec_options属性上

        context={
            "categories": get_categories(),   # 商品分类
            "breadcrumb": get_breadcrumb(category),  # 面包屑导航
            "spu":spu,  # 当前sku所对应的spu模型类
            "sku":sku, # 当前显示的sku模型类
            "category":category,  # 当前的显示sku所属的三级类别
            'spec_qs': spu_spec_qs, # 当前sku商品的所有规格及规格选项
        }

        return render(request, 'detail.html', context)


# 测试
# class DetailView(View):
#     """商品详情页残缺版"""
#     def get(self,request,sku_id):
#
#         try:
#             # 通过前端传来的id取数据库中查找商品信息
#             sku = SKU.objects.get(id= sku_id)
#         except SKU.DoesNotExist:
#             return render(request,'404.html')
#         category = sku.category    # 获取当前sku所对应的所有三级分类
#         spu = sku.spu  # 获取当前sku所对应的spu信息
#
#         current_category = sku.specs.all()
#         current_category_ids = []
#         for current in current_category:
#             current_category_ids.append(current.option_id)
#
#
#         temp_category = spu.sku_set.all()
#         temp_category_dict_ids = {}
#         for temp in temp_category:
#             temp_qs = temp.specs.all()
#             temp_category_ids = []
#             for option in temp_qs:
#                 temp_category_ids.append(option.option_id)
#             temp_category_dict_ids[tuple(temp_category_ids)] = temp.id
#
#
#         spu_spec_qs = spu.specs.order_by(("id")) # 查寻所有的spu规格
#         for index,spec in enumerate(spu_spec_qs):
#             # 通过规格信息表去查询每个规格下的所有规格选项表（例如：颜色规格下黄色，红色等规格选项）
#             spec_options_qs = spec.options.all()
#             temp_ids = current_category_ids[:]
#             for option in spec_options_qs:  # 遍历当前规格下的所有选项
#                 temp_ids[index] = option.id
#                 option.sku_id = temp_category_dict_ids.get(tuple(temp_ids))  #  给每个选项都绑定一个id，当点击时，跳转到对应id页面（此处以写死）
#             spec.spec_options = spec_options_qs # 把规格下的所有选项绑定到规格对象的spec_options属性上
#
#         context={
#             "categories": get_categories(),   # 商品分类
#             "breadcrumb": get_breadcrumb(category),  # 面包屑导航
#             "spu":spu,  # 当前sku所对应的spu模型类
#             "sku":sku, # 当前显示的sku模型类
#             "category":category,  # 当前的显示sku所属的三级类别
#             'spec_qs': spu_spec_qs, # 当前sku商品的所有规格及规格选项
#         }
#
#         return render(request,'detail.html',context)


class DetailVisitView(View):
    """记录访问商品数量"""
    def post(self,request,category_id):
        try:  # 获得当前id是否存在
            category = GoodsCategory.objects.get(id=category_id)
        except GoodsCategory.DoesNotExist:
            return http.HttpResponseForbidden('商品类别不存在')

        date = timezone.localdate()   #  自动获取当前日期（年-月-日）
        try:   # 在新建的GoodsVisitCount中查询今天当前商品是否已访问过，category为外建，关联三级分类表
            count_data = GoodsVisitCount.objects.get(category=category,date=date)
            # count_data = GoodsVisitCount.objects.get(category=category, date=date)
        except GoodsVisitCount.DoesNotExist:
            # 如果今天尚未访问，则新建纪录
            count_data = GoodsVisitCount(
                category=category
            )
        count_data.count += 1      # 访问记录加1
        count_data.save()           # 保存

        return http.JsonResponse({'code':RETCODE.OK,'errmsg':"OK"})







